/*
 * Copyright (c) 2022, IMMORTA Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice, this list
 *   of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice, this
 *   list of conditions and the following disclaimer in the documentation and/or
 *   other materials provided with the distribution.
 *
 * - Neither the name of IMMORTA Inc. nor the names of its
 *   contributors may be used to endorse or promote products derived from this
 *   software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef ERM_REG_ACCESS_H
#define ERM_REG_ACCESS_H

/*!
 * @file erm_reg_access.h
 * @brief This file declares or defines erm register access functions
 */

/*******Includes***************************************************************/
#include "erm_drv.h"

/*******Definitions************************************************************/
#define ERM_SCR_SSCIE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_SCR_SSCIE_Pos)) & ERM_SCR_SSCIE_Msk)
#define ERM_SCR_SNCIE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_SCR_SNCIE_Pos)) & ERM_SCR_SNCIE_Msk)
#define ERM_SCR_SEENE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_SCR_SEENE_Pos)) & ERM_SCR_SEENE_Msk)
#define ERM_SCR_SEDEE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_SCR_SEDEE_Pos)) & ERM_SCR_SEDEE_Msk)

#if (CONFIG_ERM_FLASH_SEPARATED_ECC_CONTROL == 0U)
#define ERM_FCR_FSCIE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_FCR_FSCIE_Pos)) & ERM_FCR_FSCIE_Msk)
#define ERM_FCR_FNCIE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_FCR_FNCIE_Pos)) & ERM_FCR_FNCIE_Msk)
#define ERM_FCR_FEENE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_FCR_FEENE_Pos)) & ERM_FCR_FEENE_Msk)
#define ERM_FCR_FEDEE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_FCR_FEDEE_Pos)) & ERM_FCR_FEDEE_Msk)
#else
#define ERM_PFCR_PFSCIE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_PFCR_PFSCIE_Pos)) & ERM_PFCR_PFSCIE_Msk)
#define ERM_PFCR_PFNCIE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_PFCR_PFNCIE_Pos)) & ERM_PFCR_PFNCIE_Msk)
#define ERM_PFCR_PFEENE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_PFCR_PFEENE_Pos)) & ERM_PFCR_PFEENE_Msk)
#define ERM_PFCR_PFEDEE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_PFCR_PFEDEE_Pos)) & ERM_PFCR_PFEDEE_Msk)

#define ERM_DFCR_DFSCIE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_DFCR_DFSCIE_Pos)) & ERM_DFCR_DFSCIE_Msk)
#define ERM_DFCR_DFNCIE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_DFCR_DFNCIE_Pos)) & ERM_DFCR_DFNCIE_Msk)
#define ERM_DFCR_DFEENE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_DFCR_DFEENE_Pos)) & ERM_DFCR_DFEENE_Msk)
#define ERM_DFCR_DFEDEE(x)    (((uint32_t)(((uint32_t)(x))<<ERM_DFCR_DFEDEE_Pos)) & ERM_DFCR_DFEDEE_Msk)
#endif

/*******APIs*******************************************************************/
void ERM_REG_SetSramEccEventEnable(ERM_Type* regBase, erm_ecc_event_t event, bool enable);
void ERM_REG_SetFlashEccEventEnable(ERM_Type* regBase, erm_ecc_event_t event, bool enable);

#if defined(__cplusplus)
extern "C" {
#endif

/*!
 * @brief ERM Enable/Disable sram ecc encode
 *
 * @param[in] regBase: The ERM register base address
 * @param[in] enable State
 *            - true: Enable the sram ecc encode
 *            - false: Disable the sram ecc encode
 * @return None
 */
static inline void ERM_REG_SetSramEccEncodeEnable(ERM_Type* regBase, bool enable)
{
    regBase->SCR = (regBase->SCR & ~ERM_SCR_SEENE_Msk) | ERM_SCR_SEENE(enable ? 1U : 0U);
}

/*!
 * @brief ERM Enable/Disable sram ecc decode
 *
 * @param[in] regBase: The ERM register base address
 * @param[in] enable State
 *            - true: Enable the sram ecc decode
 *            - false: Disable the sram ecc decode
 * @return None
 */
static inline void ERM_REG_SetSramEccDecodeEnable(ERM_Type* regBase, bool enable)
{
    regBase->SCR = (regBase->SCR & ~ERM_SCR_SEDEE_Msk) | ERM_SCR_SEDEE(enable ? 1U : 0U);
}

/*!
 * @brief ERM Enable/Disable flash ecc encode
 *
 * @param[in] regBase: The ERM register base address
 * @param[in] enable State
 *            - true: Enable the flash ecc encode
 *            - false: Disable the flash ecc encode
 * @return None
 */
static inline void ERM_REG_SetFlashEccEncodeEnable(ERM_Type* regBase, bool enable)
{
#if (CONFIG_ERM_FLASH_SEPARATED_ECC_CONTROL == 0U)
    regBase->FCR = (regBase->FCR & ~ERM_FCR_FEENE_Msk) | ERM_FCR_FEENE(enable ? 1U : 0U);
#else
    regBase->PFCR = (regBase->PFCR & ~ERM_PFCR_PFEENE_Msk) | ERM_PFCR_PFEENE(enable ? 1U : 0U);
    regBase->DFCR = (regBase->DFCR & ~ERM_DFCR_DFEENE_Msk) | ERM_DFCR_DFEENE(enable ? 1U : 0U);
#endif
}

/*!
 * @brief ERM Enable/Disable flash ecc decode
 *
 * @param[in] regBase: The ERM register base address
 * @param[in] enable State
 *            - true: Enable the flash ecc decode
 *            - false: Disable the flash ecc decode
 * @return None
 */
static inline void ERM_REG_SetFlashEccDecodeEnable(ERM_Type* regBase, bool enable)
{
#if (CONFIG_ERM_FLASH_SEPARATED_ECC_CONTROL == 0U)
    regBase->FCR = (regBase->FCR & ~ERM_FCR_FEDEE_Msk) | ERM_FCR_FEDEE(enable ? 1U : 0U);
#else
    regBase->PFCR = (regBase->PFCR & ~ERM_PFCR_PFEDEE_Msk) | ERM_PFCR_PFEDEE(enable ? 1U : 0U);
    regBase->DFCR = (regBase->DFCR & ~ERM_DFCR_DFEDEE_Msk) | ERM_DFCR_DFEDEE(enable ? 1U : 0U);
#endif
}

/*!
 * @brief ERM Is sram single-bit interrupt enable
 *
 * @param[in] regBase: The ERM register base address
 * @return - true: The sram single-bit interrupt is enable
 *         - false: The sram single-bit interrupt is disable
 */
static inline bool ERM_REG_IsSramSinglebitIntEnable(ERM_Type* regBase)
{
    return ((bool)((regBase->SCR & ERM_SCR_SSCIE_Msk) >> ERM_SCR_SSCIE_Pos));
}

/*!
 * @brief ERM Is sram non-correctable interrupt enable
 *
 * @param[in] regBase: The ERM register base address
 * @return - true: The sram non-correctable interrupt is enable
 *         - false: The sram non-correctable interrupt is disable
 */
static inline bool ERM_REG_IsSramNonCorrectableIntEnable(ERM_Type* regBase)
{
    return ((bool)((regBase->SCR & ERM_SCR_SNCIE_Msk) >> ERM_SCR_SNCIE_Pos));
}

/*!
 * @brief ERM Is flash single-bit interrupt enable
 *
 * @param[in] regBase: The ERM register base address
 * @return - true: The flash single-bit interrupt is enable
 *         - false: The flash single-bit interrupt is disable
 */
static inline bool ERM_REG_IsFlashSinglebitIntEnable(ERM_Type* regBase)
{
#if (CONFIG_ERM_FLASH_SEPARATED_ECC_CONTROL == 0U)
    return ((bool)((regBase->FCR & ERM_FCR_FSCIE_Msk) >> ERM_FCR_FSCIE_Pos));
#else
    bool retValue;

    retValue = ((bool)((regBase->PFCR & ERM_PFCR_PFSCIE_Msk) >> ERM_PFCR_PFSCIE_Pos));
    retValue |= ((bool)((regBase->DFCR & ERM_DFCR_DFSCIE_Msk) >> ERM_DFCR_DFSCIE_Pos));

    return retValue;
#endif
}

/*!
 * @brief ERM Is flash non-correctable interrupt enable
 *
 * @param[in] regBase: The ERM register base address
 * @return - true: The flash non-correctable interrupt is enable
 *         - false: The flash non-correctable interrupt is disable
 */
static inline bool ERM_REG_IsFlashNonCorrectableIntEnable(ERM_Type* regBase)
{
#if (CONFIG_ERM_FLASH_SEPARATED_ECC_CONTROL == 0U)
    return ((bool)((regBase->FCR & ERM_FCR_FNCIE_Msk) >> ERM_FCR_FNCIE_Pos));
#else
    bool retValue;

    retValue = ((bool)((regBase->PFCR & ERM_PFCR_PFNCIE_Msk) >> ERM_PFCR_PFNCIE_Pos));
    retValue |= ((bool)((regBase->DFCR & ERM_DFCR_DFNCIE_Msk) >> ERM_DFCR_DFNCIE_Pos));

    return retValue;
#endif
}

/*!
 * @brief ERM Get sram single-bit correction event flag
 *
 * @param[in] regBase: The ERM register base address
 * @return true: Sram single-bit correction event is detected
 *         flase: Sram single-bit correction event is not detected
 */
static inline bool ERM_REG_GetSramSinglebitEccEvent(ERM_Type* regBase)
{
    return ((bool)((regBase->SSR & ERM_SSR_SSBC_Msk) >> ERM_SSR_SSBC_Pos));
}

/*!
 * @brief ERM Get sram non-correction event flag
 *
 * @param[in] regBase: The ERM register base address
 * @return true: Sram non-correction correction event is detected
 *         flase: Sram non-correction correction event is not detected
 */
static inline bool ERM_REG_GetSramNonCorrectableEccEvent(ERM_Type* regBase)
{
    return ((bool)((regBase->SSR & ERM_SSR_SNCE_Msk) >> ERM_SSR_SNCE_Pos));
}

/*!
 * @brief ERM Get flash single-bit correction event flag
 *
 * @param[in] regBase: The ERM register base address
 * @return true: Flash single-bit correction event is detected
 *         flase: Flash single-bit correction event is not detected
 */
static inline bool ERM_REG_GetFlashSinglebitEccEvent(ERM_Type* regBase)
{
#if (CONFIG_ERM_FLASH_SEPARATED_ECC_CONTROL == 0U)
    return ((bool)((regBase->FSR & ERM_FSR_FSBC_Msk) >> ERM_FSR_FSBC_Pos));
#else
    bool retValue;

    retValue = ((bool)((regBase->PFSR & ERM_PFSR_PFSBC_Msk) >> ERM_PFSR_PFSBC_Pos));
    retValue |= ((bool)((regBase->DFSR & ERM_DFSR_DFSBC_Msk) >> ERM_DFSR_DFSBC_Pos));

    return retValue;
#endif
}

/*!
 * @brief ERM Get flash non-correction event flag
 *
 * @param[in] regBase: The ERM register base address
 * @return true: Flash non-correction correction event is detected
 *         flase: Flash non-correction correction event is not detected
 */
static inline bool ERM_REG_GetFlashNonCorrectableEccEvent(ERM_Type* regBase)
{
#if (CONFIG_ERM_FLASH_SEPARATED_ECC_CONTROL == 0U)
    return ((bool)((regBase->FSR & ERM_FSR_FNCE_Msk) >> ERM_FSR_FNCE_Pos));
#else
    bool retValue;

    retValue = ((bool)((regBase->PFSR & ERM_PFSR_PFNCE_Msk) >> ERM_PFSR_PFNCE_Pos));
    retValue |= ((bool)((regBase->DFSR & ERM_DFSR_DFNCE_Msk) >> ERM_DFSR_DFNCE_Pos));

    return retValue;
#endif
}

/*!
 * @brief ERM Clear sram single-bit event flag
 *
 * @param[in] regBase: The ERM register base address
 * @return None
 */
static inline void ERM_REG_ClearSramSinglebitEccEvent(ERM_Type* regBase)
{
    regBase->SSR = regBase->SSR | ERM_SSR_SSBC_Msk;
}

/*!
 * @brief ERM Clear sram non-correctable event flag
 *
 * @param[in] regBase: The ERM register base address
 * @return None
 */
static inline void ERM_REG_ClearSramNonCorrectableEccEvent(ERM_Type* regBase)
{
    regBase->SSR = regBase->SSR | ERM_SSR_SNCE_Msk;
}

/*!
 * @brief ERM Clear flash single-bit event flag
 *
 * @param[in] regBase: The ERM register base address
 * @return None
 */
static inline void ERM_REG_ClearFlashSinglebitEccEvent(ERM_Type* regBase)
{
#if (CONFIG_ERM_FLASH_SEPARATED_ECC_CONTROL == 0U)
    regBase->FSR = regBase->FSR | ERM_FSR_FSBC_Msk;
#else
    regBase->PFSR = regBase->PFSR | ERM_PFSR_PFSBC_Msk;
    regBase->DFSR = regBase->DFSR | ERM_DFSR_DFSBC_Msk;
#endif
}

/*!
 * @brief ERM Clear flash non-correctable event flag
 *
 * @param[in] regBase: The ERM register base address
 * @return None
 */
static inline void ERM_REG_ClearFlashNonCorrectableEccEvent(ERM_Type* regBase)
{
#if (CONFIG_ERM_FLASH_SEPARATED_ECC_CONTROL == 0U)
    regBase->FSR = regBase->FSR | ERM_FSR_FNCE_Msk;
#else
    regBase->PFSR = regBase->PFSR | ERM_PFSR_PFNCE_Msk;
    regBase->DFSR = regBase->DFSR | ERM_DFSR_DFNCE_Msk;
#endif
}

/*!
 * @brief ERM Get sram single-bit error address
 *
 * @param[in] regBase: The ERM register base address
 * @return Single-bit error address
 */
static inline uint32_t ERM_REG_GetSramSinglebitAddr(ERM_Type* regBase)
{
    return ((uint32_t)regBase->SSEA);
}

/*!
 * @brief ERM Get sram non-correctalbe error address
 *
 * @param[in] regBase: The ERM register base address
 * @return Non-correctalbe error address
 */
static inline uint32_t ERM_REG_GetSramNonCorrectableAddr(ERM_Type* regBase)
{
    return ((uint32_t)regBase->SNEA);
}

#if (CONFIG_ERM_FLASH_SEPARATED_ECC_CONTROL == 0U)
/*!
 * @brief ERM Get flash single-bit error address
 *
 * @param[in] regBase: The ERM register base address
 * @return Single-bit error address
 */
static inline uint32_t ERM_REG_GetFlashSinglebitAddr(ERM_Type* regBase)
{
    return ((uint32_t)regBase->FSEA);
}

/*!
 * @brief ERM Get flash non-correctalbe error address
 *
 * @param[in] regBase: The ERM register base address
 * @return Non-correctalbe error address
 */
static inline uint32_t ERM_REG_GetFlashNonCorrectableAddr(ERM_Type* regBase)
{
    return ((uint32_t)regBase->FNEA);
}
#else
/*!
 * @brief ERM Get Pflash single-bit error address
 *
 * @param[in] regBase: The ERM register base address
 * @return Single-bit error address
 */
static inline uint32_t ERM_REG_GetPflashSinglebitAddr(ERM_Type* regBase)
{
    return ((uint32_t)regBase->PFSEA);
}

/*!
 * @brief ERM Get Pflash non-correctalbe error address
 *
 * @param[in] regBase: The ERM register base address
 * @return Non-correctalbe error address
 */
static inline uint32_t ERM_REG_GetPflashNonCorrectableAddr(ERM_Type* regBase)
{
    return ((uint32_t)regBase->PFNEA);
}

/*!
 * @brief ERM Get Dflash single-bit error address
 *
 * @param[in] regBase: The ERM register base address
 * @return Single-bit error address
 */
static inline uint32_t ERM_REG_GetDflashSinglebitAddr(ERM_Type* regBase)
{
    return ((uint32_t)regBase->DFSEA);
}

/*!
 * @brief ERM Get Dflash non-correctalbe error address
 *
 * @param[in] regBase: The ERM register base address
 * @return Non-correctalbe error address
 */
static inline uint32_t ERM_REG_GetDflashNonCorrectableAddr(ERM_Type* regBase)
{
    return ((uint32_t)regBase->DFNEA);
}
#endif

#if defined(__cplusplus)
}
#endif

#endif /*ERM_REG_ACCESS_H*/

/*******EOF********************************************************************/
